﻿using System.Collections.Generic;
using System.Threading;

namespace Fly.FastReflection
{
    /// <summary>
    /// 快速反射缓存类
    /// </summary>
    /// <typeparam name="TKey"></typeparam>
    /// <typeparam name="TValue"></typeparam>
    public abstract class FastReflectionCache<TKey, TValue> : IFastReflectionCache<TKey, TValue>
    {
        private readonly Dictionary<TKey, TValue> _mCache = new Dictionary<TKey, TValue>();
        private readonly ReaderWriterLockSlim _mRwLock = new ReaderWriterLockSlim();

        public TValue Get(TKey key)
        {
            TValue value;

            _mRwLock.EnterReadLock();
            bool cacheHit = _mCache.TryGetValue(key, out value);
            _mRwLock.ExitReadLock();

            if (cacheHit) return value;

            _mRwLock.EnterWriteLock();
            if (!_mCache.TryGetValue(key, out value))
            {
                try
                {
                    value = Create(key);
                    _mCache[key] = value;
                }
                finally
                {
                    _mRwLock.ExitWriteLock();
                }
            }

            return value;
        }

        protected abstract TValue Create(TKey key);
    }
}
